package com.fredhat.tvshowrenamer.matcher;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.*;

import com.fredhat.tvshowrenamer.Configuration;
import com.fredhat.tvshowrenamer.TVShow;
import com.fredhat.tvshowrenamer.TVShowEpisode;
import com.fredhat.tvshowrenamer.parser.TVParser;
import com.fredhat.tvshowrenamer.parser.tvcom.TVComParser;

public class DateMatcher extends AbstractMatcher {
	private int stringConversions;
	private String[] possibleFormats;
	
	public DateMatcher(Configuration config) {
		super(config);
		stringConversions = 0;
		possibleFormats = new String[]{
			"MM-dd-yy",
			"MMM-dd-yyyy",
			"MM-dd-yyyy",
			"MMMMMMMMMMM-dd-yyyy",
		};
	}
	
	public TVShowEpisode matchingShowEpisode(TVShow tvShow, File file) {
		logger.debug("Checking for DateMatcher pattern match on file "+file.getName());
		for(int i=0; i<getConfiguration().getDateRegexes().length; i++) {
			logger.debug("Trying regex "+getConfiguration().getDateRegexes()[i]);
			Pattern pattern = Pattern.compile(getConfiguration().getDateRegexes()[i]);
			Matcher matcher = pattern.matcher(file.getName());
			if (!matcher.matches())
				continue;

			logger.debug("Regex "+getConfiguration().getDateRegexes()[i]+" matches.");
			if (matcher.groupCount() < 3) {
				logger.error("Date matching regex "+getConfiguration().getDateRegexes()[i]+
						" requires at least three groups");
				continue;
			} else if (matcher.groupCount() > 3) {
				logger.warn("Date matching regex "+getConfiguration().getDateRegexes()[i]+
						" has more than three groups.  Ignoring extras.");
			}

			String[] dateStaging = processDateStaging(matcher.group(1), 
					matcher.group(2), matcher.group(3));
			
			String rawDate = dateStaging[0]+"-"+dateStaging[1]+"-"+dateStaging[2];
			for(int j=0; j<possibleFormats.length; j++) {
				logger.debug("Checking format "+possibleFormats[j]+" against "+rawDate);
				SimpleDateFormat sdf = new SimpleDateFormat(possibleFormats[j]);
				//sdf.setLenient(true);
				try {
					Date date = sdf.parse(rawDate);
					Calendar cal = Calendar.getInstance();
					cal.setTime(date);
					logger.debug("Success!");
					return calendarToEpisode(tvShow, cal);
				} catch (ParseException e) {
					logger.debug("Failed.");
				}
			}
		}
		
		return null;
	}

	// If possible, force the year to be four digits, and in the format MM-DD-YYYY
	private String[] processDateStaging(String p1, String p2, String p3) {
		if (p1.length() == 2 && p2.length() == 2 && p3.length() == 2) {
			try {
				int y = Integer.parseInt(p3);
				if (2000+y <= Calendar.getInstance().get(Calendar.YEAR)) {
					y+= 2000;
				} else {
					y+= 1900;
				}
				return new String[]{p1, p2, Integer.toString(y)};
			} catch (NumberFormatException e) {}
		} else if (p1.length() == 4 && p2.length() == 2 && p3.length() == 2) {
			return new String[]{p2, p3, p1};
		}
		
		// Default is to make no staging format changes at all
		return new String[]{p1, p2, p3};
	}
	
	private TVShowEpisode calendarToEpisode(TVShow tvShow, Calendar calendar) {
		String dateString = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
		logger.debug("Converting "+tvShow.getName()+" air date "+dateString+
				" to episode number");
		
		//TVDBParser tvDB = new TVDBParser();
		//return tvDB.getEpisodeFromAirDate(tvShow, calendar);
		TVParser parser = new TVComParser();
		return parser.getEpisodeFromAirDate(tvShow, calendar);
	}
}
